package com.cloudptt.api.product.func.sys.fsm;

import com.cloudptt.api.comm.CommDlg;
import com.cloudptt.api.models.ErrInfo;
import com.cloudptt.api.models.ExtStrInfo;
import com.cloudptt.api.product.ISysOperator;
import com.cloudptt.api.product.func.IFunc;
import com.cloudptt.api.product.func.call.group.fsm.RollbackTimer;
import com.cloudptt.api.product.func.sys.SysFunc;
import com.cloudptt.api.product.func.sys.SysStateInfo;
import com.cloudptt.api.product.func.sys.listener.SysListener;
import com.cloudptt.api.product.log.Log;
import com.cloudptt.api.product.operator.SysOperator;
import com.cloudptt.api.product.res.Resource;
import com.mcptt.config.local.SysConfig;
import com.mcptt.http.operator.IHttpOpCb;

import android.content.Context;

public class SysAgent implements ISysState,ISysOperator,IHttpOpCb {


	private Context ctx = null;
	private SysOperator operator = null;
	private SysConfig config = null;

	private ISysState curSysState = null;
	private SysStateInfo curStateInfo = null;
	private int publishResult = 0;

	//	private Queue<String> downloadQueue = null;
	private SysListener sysListener = null;
	//	private SysAddrListener sysAddrListener = null;
	private RollbackTimer rollbackTimer = null;
	private IFunc superFunc = null;



	private boolean networkDisconnect = false;

	public SysAgent(Context ctx,SysConfig config,SysOperator operator,IFunc superFunc,boolean networkDisconnect)
	{
		Log.d(SysFunc.Log_Key, "SysFunc networkDisconnect = " + networkDisconnect);
		this.ctx = ctx;
		this.config = config;
		this.operator = operator;
		//		this.sysAddrListener = addrListener;
		this.curSysState = new SvrStopState(this);
		this.superFunc = superFunc;
		this.networkDisconnect = networkDisconnect;
		//		this.downloadQueue = new LinkedList<String>();
	}

	public void goToState(int nextState,int cause)
	{
		Log.d(SysFunc.Log_Key, "goToState:["+ SysStateInfo.stateTag(this.curSysState.getState()) + " to "+ SysStateInfo.stateTag(nextState) + "] cause = " + cause);
		ISysState state = null;
		switch (nextState) 
		{
		case SysStateInfo.SysState_SvrStopState:
			state = new SvrStopState(this);
			break;
		case SysStateInfo.SysState_SvrStartState:
			state = new SvrStartState(this);
			Log.d(SysFunc.Log_Key, "goToState setCurState SvrStartState");	
			break;
			//		case SysStateInfo.SysState_HttpGetingState:
			//			state = new HttpGetingState(ctx,this);
			//			break;
			//		case SysStateInfo.SysState_HttpGetSucState:
			//			state = new HttpGetSucState(this);
			//			break;
		case SysStateInfo.SysState_HttpAuthingState:
			if (cause == SysStateInfo.Cause_Relogin) {
				state = new HttpAuthingState(ctx, this,true);
			}
			else {
				state = new HttpAuthingState(ctx, this,false);
			}
			break;
		case SysStateInfo.SysState_HttpAuthSucState:
			state = new HttpAuthSucState(this);
			break;
			//		case SysStateInfo.SysState_InitState:
			//			state = new InitState(this);
			//			break;
		case SysStateInfo.SysState_SipAuthingState:
			state = new SipAuthingState(ctx,this);
			break;
		case SysStateInfo.SysState_SipAuthSucState:
			state = new SipAuthSucState(this);
			break;
		default:
			Log.d(SysFunc.Log_Key, "Illegal state="+ nextState);
			return;//!!!
		}
		this.setCurState(state,cause);
	}
	public void setSysListener(SysListener sysListener) 
	{
		this.sysListener = sysListener;
	}

	public SysStateInfo getSysStateInfo()
	{
		return curStateInfo;
	}

	private void setCurState(ISysState sysState,int cause) 
	{
		Log.d(SysFunc.Log_Key, "setCurState sysState = " + sysState + " cause = " + cause);	
		this.curSysState.destory();
		this.curSysState = sysState;

		int state = curSysState.getState();

		if(state ==  SysStateInfo.SysState_SvrStartState)
		{
			boolean isInvalidUser = config.getMcpttLoginInfo().isInvalidUser();
			Log.d(SysFunc.Log_Key, "setCurState isInvalidUser = "+ isInvalidUser);
			if(isInvalidUser)
			{
				cause = SysStateInfo.Cause_Input;
			}
		}
		curStateInfo = new SysStateInfo(state,cause);
		if(sysListener != null)
		{
			sysListener.onSysState(curStateInfo);
		}
		else
		{
			Log.d(SysFunc.Log_Key, "setCurState sysListener = null");	
		}
		doNextActionBySysState(state,cause);
	}

	private void doNextActionBySysState(int state,int cause)
	{
		if(cause != SysStateInfo.Cause_Suc
			&& cause != SysStateInfo.Cause_Relogin)
		{
			return;
		}
		else if(state == SysStateInfo.SysState_SvrStartState
				&& cause == SysStateInfo.Cause_Input)
		{
			this.goToState(SysStateInfo.SysState_SipAuthingState, SysStateInfo.Cause_Suc);
		}
		else if(state == SysStateInfo.SysState_SvrStartState)
		{
			Log.d(SysFunc.Log_Key, "doNextActionBySysState networkDisconnect = " + networkDisconnect);
			if(networkDisconnect) {
				if(cause != SysStateInfo.Cause_Relogin)
				{
					doSysAction(SysConst.SysAction_ReAuth);
				}
				else {
					doSysAction(SysConst.SysAction_Auth);
				}
			}
		}
		//		if(state == SysStateInfo.SysState_HttpGetSucState)
		//		{
		//			doSysAction(SysConst.SysAction_HttpAuth);
		//		}
		else if(state == SysStateInfo.SysState_HttpAuthSucState)
		{
			doSysAction(SysConst.SysAction_SipAuth);
		}
		else if(state == SysStateInfo.SysState_SipAuthSucState)
		{
			//			this.rollbackTimer = new RollbackTimer(5,this);
			//			downloadAddrList();
		}
	}

	public void doSipAuth()
	{
		Log.d(SysFunc.Log_Key, "doSipAuth");
		operator.login();
	}
	public void doHttpGet()
	{
		Log.d(SysFunc.Log_Key, "doHttpGet");
		operator.httpGet(this);
	}
	public void doHttpAuth()
	{
		Log.d(SysFunc.Log_Key, "doHttpAuth");
		operator.httpAuth(this);
	}
	public void doSipUnAuth()
	{
		Log.d(SysFunc.Log_Key, "doSipUnAuth");
		operator.logout();
	}

	//	public void downloadAddrList()
	//	{
	//		Log.d(SysFunc.Log_Key, "downloadAddrList");
	//		this.configCenter.deleteAllGroupUser();
	//
	//		this.configCenter.deleteAllGroupUser();
	//		//				sendSubscribe(UserInfo.McType_Ptt);
	//		String mcpttId = this.config.getMcInfo().getMcpttId();
	//		pushUserProfileNotifyStr(UserInfo.McType_Ptt,mcpttId);
	//
	//		String mcvideoId = this.config.getMcInfo().getMcvideoId();
	//		pushUserProfileNotifyStr(UserInfo.McType_Video,mcvideoId);
	//
	//		String mcdataId = this.config.getMcInfo().getMcdataId();
	//		Log.d(SysFunc.Log_Key, "ACTION_SIP_RELOGIN mcdataId = " + mcdataId);
	//		pushUserProfileNotifyStr(UserInfo.McType_Data,mcdataId);
	//
	//		recvNotifyFromQueue();
	//	}

	@Override
	public int doSysAction(int sysAction) {
		Log.d(SysFunc.Log_Key,"recevSysMsg curSysState =  " + SysStateInfo.stateTag(this.curSysState.getState())  + " sysAction = " + SysConst.sysActionTag(sysAction));
		// TODO Auto-generated method stub
		return curSysState.doSysAction(sysAction);
	}

	@Override
	public void recevSysMsg(int sysMsgId) {
		// TODO Auto-generated method stub
		Log.d(SysFunc.Log_Key,"recevSysMsg curSysState =  " + SysStateInfo.stateTag(this.curSysState.getState())  +  " sysMsgId = " +SysConst.sysMsgTag(sysMsgId));
		curSysState.recevSysMsg(sysMsgId);
//		if(sysMsgId == SysConst.SysMsg_Sip_Auth_Failed
//				|| sysMsgId == SysConst.SysMsg_Sip_Auth_Timeout)
//		{
//			String str = Resource.getString("login_failed");
//			CommDlg.showShortToast(ctx, str);
//		}
	}


	@Override
	public int getState() {
		// TODO Auto-generated method stub
		return curSysState.getState();
	}


	public void logout() {
		// TODO Auto-generated method stub
		if(rollbackTimer != null)
		{
			rollbackTimer.cancelTimer();
			rollbackTimer = null;
		}
		if(config != null)
		{
			config.getMcpttLoginInfo().clearMcpttLoginInfo();
		}
		this.recevSysMsg(SysConst.SysMsg_Logout);
		//		this.doSipUnAuth();
		//		this.curSysState = new SvrStartState(this);
	}

	@Override
	public void destory() {
		// TODO Auto-generated method stub
		if(rollbackTimer != null)
		{
			rollbackTimer.cancelTimer();
			rollbackTimer = null;
		}
		this.curSysState.destory();
	}

	//	@Override
	//	public void httpAuthSuc(FinalResult finalResult) {
	//		// TODO Auto-generated method stub
	//		recevHttpResult(true);
	//	}

	public void onSipAuthResult(int code,String name,String num)
	{
		Log.d(SysFunc.Log_Key, "onSipAuthResult code = " +code + " name = " + name + " num = " + num);
		if(sysListener != null) {
			this.sysListener.onSipAuthResult(code);
		}
		if (code/100 != 2)
		{
			String errStr = ExtStrInfo.getErrDesc(ctx,ExtStrInfo.Title_pttreg,code);
			Log.d(SysFunc.Log_Key, "onSipAuthResult errStr = " + errStr);

			if(errStr != null
			&& !errStr.equals(""))
			{
				CommDlg.showToast(ctx, errStr);
			}
			else
			{
				String str = Resource.getString("login_failed");
				CommDlg.showShortToast(ctx, str);
			}
			//this.doSipUnAuth();
			if(code == 404 || code == 604)
			{
				recevSysMsg(SysConst.SysMsg_Sip_Auth_Relogin);
			}
//			else if(code == 408)
//			{
//				//recevSysMsg(SysConst.SysMsg_Sip_Auth_Timeout);
//				recevSysMsg(SysConst.SysMsg_Sip_Auth_Relogin);
//			}
			else
			{
				recevSysMsg(SysConst.SysMsg_Sip_Auth_Failed);
			}
			if(superFunc != null)
			{
				superFunc.onLogined(config.getMcInfo(),config.getServerInfo(),false);
			}
		}
		else
		{
			if(networkDisconnect)
			{
				if(sysListener != null) {
					this.sysListener.onSysState(curStateInfo);
				}
//				networkDisconnect = false;
			}

			Log.d(SysFunc.Log_Key, "ACTION_SIP_RELOGIN this.config.isLogined() = " + this.config.isLogined());
			if(!this.config.isLogined())
			{
				this.config.setUserInfoAfterLoginSuc(name,num);
			}
			recevSysMsg(SysConst.SysMsg_Sip_Auth_Suc);
			this.doKeepAlive(true);
			if(superFunc != null)
			{
				superFunc.onLogined(config.getMcInfo(),config.getServerInfo(),true);
			}
		}
	}

	public void doForceDetach()
	{
		Log.d(SysFunc.Log_Key, "doForceDetach");
		if(this.sysListener != null)
		{
			this.sysListener.onForceDetach();
		}
		else
		{
			Log.d(SysFunc.Log_Key, "sysListener = null");
		}
	}

	public void doSvrRestart()
	{
		Log.d(SysFunc.Log_Key, "doSvrRestart");
		if(this.sysListener != null)
		{
			this.sysListener.onSvrRestart();
		}
		else
		{
			Log.d(SysFunc.Log_Key, "sysListener = null");
		}
	}
	public void doKeepAlive(boolean isconnected)
	{
		Log.d(SysFunc.Log_Key, "doKeepAlive isconnected = " + isconnected);
		if(this.sysListener != null)
		{
			this.sysListener.onKeepAlive(isconnected);
		}
		else
		{
			Log.d(SysFunc.Log_Key, "sysListener = null");
		}
	}
	//	}

	@Override
	public void onOpResult(int id,boolean isSuc,int cause, String str) {
		// TODO Auto-generated method stub
		if(id == IHttpOpCb.Id_Get)
		{
			if(isSuc)
			{
				this.recevSysMsg(SysConst.SysMsg_Get_Suc);
			}
			else
			{
				this.recevSysMsg(SysConst.SysMsg_Get_Failed);
			}
		}
		else if(id == IHttpOpCb.Id_Auth)
		{
			if(isSuc)
			{
				this.recevSysMsg(SysConst.SysMsg_Http_Auth_Suc);
			}
			else
			{
				this.recevSysMsg(SysConst.SysMsg_Http_Auth_Failed);
				ErrInfo errInfo = new ErrInfo(ExtStrInfo.Title_HttpAuth,cause);
				if( errInfo != null )
				{
					String errStr = errInfo.getErrDesc();
					CommDlg.show(ctx, errStr);
				}
			}
		}
	}

	public void setNetworkDisconnect(boolean networkDisconnect) {
		this.networkDisconnect = networkDisconnect;
		Log.d(SysFunc.Log_Key, "setNetworkDisconnect networkDisconnect = " + networkDisconnect);
		if(networkDisconnect) {
			doSysAction(SysConst.SysAction_Auth);
		}
	}
}
